﻿Imports System.Text
Imports System.IO
Imports System.Runtime.InteropServices
Imports EnvDTE
Imports Microsoft.VisualStudio.OLE.Interop
Imports Microsoft.VisualStudio.Shell
Imports Microsoft.VisualStudio.Text
Imports Microsoft.VisualStudio.TextManager.Interop
Imports System.ComponentModel.Composition

Namespace VsSpeakerCompanion
	''' <summary>
	''' Exposes core Visual Studio functionality
	''' </summary>
	''' <remarks>
	''' The only reason we need this is because we need to get to an IServiceProvider from a MEF component which isn't easily supported right now.
	''' In later releases of Visual Studio 2010 it may be possible to access an IServiceProvider from a MEF component and when that
	''' happens this code won't be needed anymore
	''' </remarks>
	Public Class VisualStudioHelper
		Private isInitialized As Boolean

		''' <summary>
		''' Gets the service provider used to get services from Visual Studio.
		''' </summary>
        Public Property ServiceProvider As System.IServiceProvider

		Friend Sub New()
		End Sub

		''' <summary>
		''' Used to construct a helper. The textbuffer will provide the service provider.
		''' </summary>
		Public Sub New(ByVal textBuffer As ITextBuffer)
			Initialize(textBuffer)
		End Sub

		<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000")>
		Private Shared Function GetServiceProviderFromTextBuffer(ByVal textBuffer As ITextBuffer) As System.IServiceProvider
            Dim objectWithSite = textBuffer.Properties.GetProperty(Of IObjectWithSite)(GetType(IVsTextBuffer))
			If objectWithSite IsNot Nothing Then
                Dim serviceProviderGuid = GetType(Microsoft.VisualStudio.OLE.Interop.IServiceProvider).GUID
                Dim ppServiceProvider = IntPtr.Zero
				' Get the service provider pointer using the Guid of the OleInterop ServiceProvider
				objectWithSite.GetSite(serviceProviderGuid, ppServiceProvider)

				If ppServiceProvider <> IntPtr.Zero Then
					' Create a System.ServiceProvider with the OleInterop ServiceProvider
                    Dim oleInteropServiceProvider As Microsoft.VisualStudio.OLE.Interop.IServiceProvider = CType(Marshal.GetObjectForIUnknown(ppServiceProvider), Microsoft.VisualStudio.OLE.Interop.IServiceProvider)
					Return New ServiceProvider(oleInteropServiceProvider)
				End If
			End If

			Return Nothing
		End Function

		''' <summary>
		''' Initializes the helper
		''' </summary>
		''' <param name="textBuffer"></param>
		Friend Sub Initialize(ByVal textBuffer As ITextBuffer)
            If Not isInitialized Then
                Me.ServiceProvider = GetServiceProviderFromTextBuffer(textBuffer)

                isInitialized = Me.ServiceProvider IsNot Nothing
            End If
		End Sub
	End Class
End Namespace